///////////////////////////////////////////////////////////////////////////
// C++ code generated with wxFormBuilder (version Jun 17 2015)
// http://www.wxformbuilder.org/
//
// PLEASE DO "NOT" EDIT THIS FILE!
///////////////////////////////////////////////////////////////////////////

#include <wx/msgdlg.h>
#include "Panel_PixelatedTextPanel.h"
#include "PixelToolsDataType.h"

///////////////////////////////////////////////////////////////////////////
WX_DEFINE_LIST(FontPixelMatrixList);
///////////////////////////////////////////////////////////////////////////
BEGIN_EVENT_TABLE(Panel_PixelatedTextPanel, wxPixelatedPanel)
	EVT_MOUSE_EVENTS(Panel_PixelatedTextPanel::wxEvent_OnMouseEvent)
	EVT_PAINT		(Panel_PixelatedTextPanel::wxEvent_OnPaint)
END_EVENT_TABLE()
Panel_PixelatedTextPanel::Panel_PixelatedTextPanel( wxWindow* parent, wxWindowID id, const wxPoint& pos):
wxPixelatedPanel(parent, id, pos)
{
	m_pclsFontPixelMatrixList = new FontPixelMatrixList();
	m_pclsCDC = new wxClientDC(this);
	m_pclsBrush = new wxBrush();
	m_pclsPen = new wxPen();
	m_pclsCurrentFocus = new wxFontPixelMatrixCoordinate();
	m_pclsPixelColor = new wxColor(DEFAULT_VALUE_PANEL_PIXEL_COLOR);
	m_pclsBackgroundColor = new wxColor(DEFAULT_VALUE_PANEL_BACKGROUND_COLOR);
	m_pclsFocusBorderColor = new wxColor(DEFAULT_VALUE_PANEL_FOCUS_BORDER_COLOR);
	m_pclsTextFont = new wxFont();
}

void Panel_PixelatedTextPanel::AppendCharacter(wxBitmap& clsBitmap)
{
	wxMemoryDC		clsMDC;
	wxColor			clsPixelColor;
	int32_t			iPosX;

	iPosX = _getPosition();
	clsMDC.SelectObject(clsBitmap);
	// Only draw visible font graph.
    for(int32_t i_PixV=0; i_PixV<clsBitmap.GetHeight(); i_PixV++)
    {
        for(int32_t i_PixH=0; i_PixH<clsBitmap.GetWidth(); i_PixH++)
        {
            clsMDC.GetPixel(i_PixH, i_PixV, &clsPixelColor);
            if(clsPixelColor == (*wxBLACK))
            {
                SetPixelUnitColor(iPosX+i_PixH, i_PixV, *m_pclsBackgroundColor);
            }
            else
            {
                SetPixelUnitColor(iPosX+i_PixH, i_PixV, *m_pclsPixelColor);
            }
        }
    }
	_addFontPixelMatrix(clsBitmap);
}

void Panel_PixelatedTextPanel::_addFontPixelMatrix(wxBitmap& clsBitmap)
{
	m_pclsFontPixelMatrixList->Append(new wxBitmap(clsBitmap));
}

uint32_t Panel_PixelatedTextPanel::_getPosition(int32_t iCharacterGraphIndex)
{
    uint32_t			uiPosX;
    uint32_t			uiIndex;
    FontPixelMatrixList::iterator	Iter;
    wxBitmap*			pFontPixelMatrix;

	uiPosX = 0;
	uiIndex = 0;

	Iter = m_pclsFontPixelMatrixList->begin();
	while((Iter != m_pclsFontPixelMatrixList->end()) && (uiIndex < (uint32_t)iCharacterGraphIndex))
	{
		pFontPixelMatrix = *Iter;
		uiPosX += pFontPixelMatrix->GetWidth();
		Iter++;
		uiIndex++;
	}
	return uiPosX;
}

void Panel_PixelatedTextPanel::OnMouseEvent(wxMouseEvent& event)
{
	uint32_t							uiPixelPosX, uiPixelSize;
	static wxFontPixelMatrixCoordinate	clsLastCoordinate;
	wxFontPixelMatrixCoordinate			clsNowCoordinate;


	uiPixelSize = GetPixelSize();
	if(0 == uiPixelSize)
	{
		uiPixelPosX = event.GetPosition().x/4;
	}
	else
	{
		uiPixelPosX = event.GetPosition().x/uiPixelSize;
	}

	_getFontGraphCoordinate(uiPixelPosX, clsNowCoordinate);

	if(event.Moving() == true)
	{
		if(clsLastCoordinate.GetIndex() != clsNowCoordinate.GetIndex())
		{
			_highLightCharacter(clsLastCoordinate, false);
			_highLightCharacter(clsNowCoordinate, true);
			clsLastCoordinate.CopyForm(clsNowCoordinate);
			m_pclsCurrentFocus->CopyForm(clsNowCoordinate);
		}
	}
	else if(event.Leaving() == true)
	{
		_highLightCharacter(clsLastCoordinate, false);
		m_pclsCurrentFocus->Reset();
	}
	else if(event.Entering() == true)
	{
		clsLastCoordinate.CopyForm(clsNowCoordinate);
		_highLightCharacter(clsNowCoordinate, true);
		m_pclsCurrentFocus->CopyForm(clsNowCoordinate);
	}
}

void Panel_PixelatedTextPanel::_highLightCharacter(wxFontPixelMatrixCoordinate& clsCoordinate, bool bHighLight)
{
	uint32_t    uiPixelSize = GetPixelSize();
	uint32_t    uiVerticalPixelNumber;

	GetPixelNumber(NULL, &uiVerticalPixelNumber);
    if((NULL != m_pclsCDC) && (NULL != m_pclsPen) && (-1 != clsCoordinate.GetIndex()))
	{
		if(true == bHighLight)
		{
            m_pclsPen->SetColour(*m_pclsFocusBorderColor);
		}
		else
		{
			m_pclsPen->SetColour(GetGridColor());
		}
		m_pclsCDC->SetPen(*m_pclsPen);
		m_pclsCDC->SetBrush(*wxTRANSPARENT_BRUSH);
		m_pclsCDC->DrawRectangle(clsCoordinate.GetPosition()*uiPixelSize, 0, clsCoordinate.GetWidth()*uiPixelSize+1, uiVerticalPixelNumber*uiPixelSize+1);
	}
}

void Panel_PixelatedTextPanel::_getFontGraphCoordinate(int32_t iPixelXPosition, wxFontPixelMatrixCoordinate& clsResult)
{
	int32_t							iPosX;
	int32_t							iCharacterIndex;
	int32_t							iWidth, iHeight;
    FontPixelMatrixList::iterator	Iter;
    wxBitmap*						pFontPixelMatrix;

	iPosX = 0;
	iCharacterIndex = -1;
	iWidth = -1;
	iHeight = -1;
	Iter = m_pclsFontPixelMatrixList->begin();

	while((Iter != m_pclsFontPixelMatrixList->end()) && (iPixelXPosition >= iPosX))
	{
		pFontPixelMatrix = *Iter;
		iWidth = pFontPixelMatrix->GetWidth();
		iHeight = pFontPixelMatrix->GetHeight();
		iCharacterIndex++;
		clsResult.SetParameter(iCharacterIndex, iPosX, iWidth, iHeight);
		iPosX += iWidth;
		Iter++;
	}
}

void Panel_PixelatedTextPanel::CleanPanel(void)
{
	uint32_t uiPixelWidth, uiPixelHeight;
	// Fill with background.
	GetPixelNumber(&uiPixelWidth, &uiPixelHeight);

	for(uint32_t i_Y=0; i_Y<uiPixelHeight; i_Y++)
	{
		for(uint32_t i_X=0; i_X<uiPixelWidth; i_X++)
		{
		    SetPixelUnitColor(i_X, i_Y, *m_pclsBackgroundColor, false);
		}
	}
	m_pclsFontPixelMatrixList->Clear();
}

void Panel_PixelatedTextPanel::SetBackgroundColor(const wxColor& clsColor)
{
	if(NULL != m_pclsBackgroundColor)
	{
		m_pclsBackgroundColor->SetRGBA(clsColor.GetRGBA());
	}
	else
	{
		m_pclsBackgroundColor = new wxColor(clsColor);
	}
	//CleanPanel();
	UpdateBackgroundColor();
}

void Panel_PixelatedTextPanel::UpdateBackgroundColor(void)
{
    uint32_t uiPixelWidth, uiPixelHeight;

	GetPixelNumber(&uiPixelWidth, &uiPixelHeight);

	for(uint32_t i_Y=0; i_Y<uiPixelHeight; i_Y++)
	{
		for(uint32_t i_X=0; i_X<uiPixelWidth; i_X++)
		{
		    if(m_pclsPixelColor->GetRGBA() != GetPixelUnitColor(i_X, i_Y))
            {
                SetPixelUnitColor(i_X, i_Y, *m_pclsBackgroundColor, false);
            }
		}
	}
}

void Panel_PixelatedTextPanel::SetPixelColor(const wxColor& clsColor)
{
	if(NULL != m_pclsPixelColor)
	{
		m_pclsPixelColor->SetRGBA(clsColor.GetRGBA());
	}
	else
	{
		m_pclsPixelColor = new wxColor(clsColor);
	}
	UpdateDrawPixelColor();
}

void Panel_PixelatedTextPanel::UpdateDrawPixelColor(void)
{
    uint32_t uiPixelWidth, uiPixelHeight;

	GetPixelNumber(&uiPixelWidth, &uiPixelHeight);

	for(uint32_t i_Y=0; i_Y<uiPixelHeight; i_Y++)
	{
		for(uint32_t i_X=0; i_X<uiPixelWidth; i_X++)
		{
		    if(m_pclsBackgroundColor->GetRGBA() != GetPixelUnitColor(i_X, i_Y))
            {
                SetPixelUnitColor(i_X, i_Y, *m_pclsPixelColor, false);
            }
		}
	}
}

void Panel_PixelatedTextPanel::SetFocusBorderColor(const wxColor& clsColor)
{
	if(NULL != m_pclsFocusBorderColor)
	{
		m_pclsFocusBorderColor->SetRGBA(clsColor.GetRGBA());
	}
	else
	{
		m_pclsFocusBorderColor = new wxColor(clsColor);
	}
}

wxColor& Panel_PixelatedTextPanel::GetBackgroundColor(void)
{
	return *m_pclsBackgroundColor;
}

wxColor& Panel_PixelatedTextPanel::GetPixelColor(void)
{
	return *m_pclsPixelColor;
}

wxColor& Panel_PixelatedTextPanel::GetBorderColor(void)
{
	return *m_pclsFocusBorderColor;
}

void Panel_PixelatedTextPanel::OnPaint(wxPaintEvent& event)
{
	wxPixelatedPanel::OnPaint();
}

Panel_PixelatedTextPanel::~Panel_PixelatedTextPanel()
{
	m_pclsFontPixelMatrixList->Clear();
    delete m_pclsFontPixelMatrixList;
	delete m_pclsCDC;
	delete m_pclsPen;
	delete m_pclsCurrentFocus;
}

void Panel_PixelatedTextPanel::SetFont(int iFontSize, wxFontFamily eFamily, wxFontStyle eStyle, wxFontWeight eWeight, bool bUnderlined, const wxString& strFace, wxFontEncoding eTextEncoding)
{
    if(NULL != m_pclsTextFont)
    {
        m_pclsTextFont->Create(iFontSize, eFamily, eStyle, eWeight, bUnderlined, strFace, eTextEncoding);
    }
}

wxFont& Panel_PixelatedTextPanel::GetFont(void)
{
    return *m_pclsTextFont;
}


